﻿using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Web.UI;
using System.Web.UI.WebControls;
using Medianamik.Core;
using Medianamik.Core.Sugar;
using Medianamik.Globalization;
using Medianamik.UI.Controls;
using Medianamik.UI.Lock;
using Telerik.Web.UI;

namespace Medianamik.UI
{
    public abstract class BaseModuleListPage : BasePage
    {
        const string _lockInfoToolTipID = "BFD7C3188ABD4CA290BE7605DCC2F5E1";
        //protected const string ActionColumnID = "F1059009C12A46269D41F7F4A5AD75D0";
        protected const string ActionColumnUniqueName = "ActionColumn";
        protected const string NameColumnUniqueName = "NameColumn";
        protected GridTemplateColumn NameColumn;

        protected override void OnInit(EventArgs e)
        {
            var cultureSelectorWindow = new BaseModalWindow { ID = "CultureSelectorWindow" };
            var deleteNodeWindow = new BaseModalWindow { ID = "deleteNodeWindow" };
            MyWindowManager.Windows.Add(deleteNodeWindow);
            MyWindowManager.Windows.Add(cultureSelectorWindow);

            var lockInfoToolTip = new LockInfoToolTip { ID = _lockInfoToolTipID };
            GridUpdatePanel.ContentTemplateContainer.Controls.Add(lockInfoToolTip);

            Grid.PagerStyle.PagerTextFormat = Translator.Translate("Medianamik_Global", "GridPagerTextFormat");

            var scriptLiteral = new LiteralControl();
            MyRadScriptBlock.Controls.Add(scriptLiteral);

            MyScriptManager.Navigate += OnNavigate;

            if (GridOptions != GridOptions.None)
            {
                NameColumn = new GridTemplateColumn
                {
                    HeaderText = GridColumnNameHeaderText,
                    UniqueName = NameColumnUniqueName,
                    ItemTemplate = new GridNameColumnTemplate(GridOptions == GridOptions.NavigateName, OnNavigate)
                };

                if (!String.IsNullOrEmpty(GridColumnNameCssClass))
                    NameColumn.ItemStyle.CssClass = GridColumnNameCssClass;

                Grid.MasterTableView.EnableColumnsViewState = false;
                Grid.MasterTableView.Columns.Add(NameColumn);
            }

            if (GridActionOptions != GridActionOptions.None)
            {
                var actionColumn = new GridTemplateColumn
                   {
                       HeaderText = "Actions",
                       UniqueName = ActionColumnUniqueName,
                       ItemTemplate = new GridActionColumnTemplate(NodeIdParamName, ManagementURL,
                            LockRequestFailed, GridActionOptions, OnActivationChanged, ReturnUrl.EncodeBase64())
                   };

                actionColumn.ItemStyle.CssClass = "Actions";
                actionColumn.HeaderStyle.HorizontalAlign = HorizontalAlign.Center;
                actionColumn.HeaderStyle.Width = Unit.Percentage(1);
                Grid.MasterTableView.EnableColumnsViewState = false;
                Grid.MasterTableView.Columns.Add(actionColumn);
            }

            if (Grid.MasterTableView.NoRecordsTemplate == null)
            {
                Grid.MasterTableView.NoRecordsTemplate = new GridNoRecordsTemplate();
            }

            if (!Page.IsPostBack)
            {
                deleteNodeWindow.OnClientClose= "deleteNodeWindowCallback";
                deleteNodeWindow.IconUrl = "/Medianamik/images/Icones/Ico_Supprimer.gif";
                deleteNodeWindow.ReloadOnShow = true;
                deleteNodeWindow.Width = Unit.Pixel(400);
                deleteNodeWindow.Height = Unit.Pixel(200);

                cultureSelectorWindow.OnClientClose= "onCultureSelected";
                cultureSelectorWindow.IconUrl = "/Medianamik/images/Icones/Ico_AjoutPage.gif";
                cultureSelectorWindow.ReloadOnShow = true;
                cultureSelectorWindow.Width = Unit.Pixel(400);
                cultureSelectorWindow.Height = Unit.Pixel(200);

                var script = String.Concat("<script type=\"text/javascript\">//<![CDATA[ \n",
                    Utility.GetDeleteElementScript(MyRadAjaxManager.ClientID,
                        Medianamik.Core.Pages.DeleteElementWindow,
                        CurrentEditionCulture.Name,DestroyOnDelete, 
                        CurrentEditionCulture.Name.Equals(String.Empty)),
                    Utility.GetCultureSelectedScript(ManagementURL,false,NodeIdParamName, ""),
                    EnableSorting ? Utility.GetRowDroppingScript(Grid.ClientID) : "",
                    " //]]></script>\n");

                if (EnableSorting)
                {
                    Grid.ClientSettings.AllowRowsDragDrop = true;
                    Grid.ClientSettings.EnableRowHoverStyle = true;
                    Grid.ClientSettings.Selecting.AllowRowSelect = true;
                    Grid.ClientSettings.Selecting.EnableDragToSelectRows = true;
                    Grid.ClientSettings.ClientEvents.OnRowDropping = "onRowDropping";
                }

                scriptLiteral.Text = script;
            }

            base.OnInit(e);
        }

        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
            Grid.ItemDataBound += ItemDataBound;
            Grid.NeedDataSource += GridNeedDataSource;
            Grid.RowDrop += OnSort;
            RadAjaxManager.GetCurrent(this).AjaxRequest += AjaxRequest;

            if (BreadcrumbTrail != null)
            {
                BreadcrumbTrail.NavigateParent += NavigateToParent;

                if (!IsPostBack)
                    LoadBreadcrumbs();
            }
        }

        protected override void OnPreRender(EventArgs e)
        {
            // Enregister le service de Lock systématiquement
            // Correction du bug : Le service de Lock n'est pas ajouté après un callback ajax.
            ScriptManager.GetCurrent(Page).Services.Add(new ServiceReference("/Medianamik/Services/LockWebService.asmx"));

            base.OnPreRender(e);
        }

        protected void ItemDataBound(object sender, GridItemEventArgs e)
        {
            if (e.Item.ItemType == GridItemType.Item || e.Item.ItemType == GridItemType.AlternatingItem)
            {
                var gridItem = (GridDataItem)e.Item;

                if (gridItem.DataItem != null)
                {
                    var node = gridItem.DataItem as Node;

                    if (node != null)
                    {
                        var editButton = (LockButton)e.Item.FindControl("EditButton");
                        new EditButtonConfigurator(node.WebSite, CurrentEditionCulture).Configure(editButton, node);
                    }
                }
            }
        }

        protected virtual void OnSort(object sender, GridDragDropEventArgs e)
        {
            if (EnableSorting && e.DraggedItems[0].OwnerGridID == Grid.ClientID)
            {
                var movedNode = NodeManager.GetNode((Guid)e.DraggedItems[0].GetDataKeyValue(Grid.MasterTableView.DataKeyNames[0]));

                if (string.IsNullOrEmpty(e.HtmlElement) && movedNode != null)
                {
                    var destinationNodeId = (Guid)e.DestDataItem.GetDataKeyValue(Grid.MasterTableView.DataKeyNames[0]);

                    var pos = e.DropPosition == GridItemDropPosition.Above
                        ? DropPosition.Above
                        : DropPosition.Below;

                    NodeManager.ChangeNodeOrder(movedNode, destinationNodeId, pos);

                    Grid.Rebind();
                }
            }
        }

        //[PrincipalPermission(SecurityAction.Assert, Role = "ElementActivationManagement ")]
        protected virtual void OnActivationChanged(object sender, CommandEventArgs e)
        {
            NodeManager.SetNodeActiveStatus(new Guid(e.CommandArgument.ToString()),
                                            CurrentEditionCulture,
                                            e.CommandName.ToLowerInvariant() == "activate");

            Grid.Rebind();
        }

        protected abstract void GridNeedDataSource(object source, GridNeedDataSourceEventArgs e);

        protected virtual void OnUnlock(object sender, EventArgs e)
        {
            var lockInfoToolTip = (RadToolTip)GridUpdatePanel.ContentTemplateContainer.FindControlR(_lockInfoToolTipID);

            lockInfoToolTip.Visible = false;
        }

        protected virtual void NavigateToParent(object sender, NavigateParentEventArgs e)
        {
            var parentId = new Guid(e.ItemID);

            if (CurrentModule.ID.Equals(parentId))
                ParentNodeId = null;
            else
                ParentNodeId = parentId;

            Navigate();
        }

        protected virtual void OnNavigate(object sender, HistoryEventArgs e)
        {
            Navigate(e.State.Get("ParentNodeId"));
        }

        protected virtual void AjaxRequest(object sender, AjaxRequestEventArgs e)
        {
            Grid.Rebind();
            GridUpdatePanel.Update();
        }

        protected override void OnCultureChanged(CultureChangedEventArgs e)
        {
            base.OnCultureChanged(e);
            Grid.Rebind();
            GridUpdatePanel.Update();
        }

        protected virtual void LockRequestFailed(object sender, CommandEventArgs e)
        {
            Grid.Rebind();
            var objectId = new Guid((string)e.CommandArgument);
            var lockInfoToolTip =
                (LockInfoToolTip)GridUpdatePanel.ContentTemplateContainer.FindControlR(_lockInfoToolTipID);
            lockInfoToolTip.ObjectId = objectId;
            lockInfoToolTip.DataBind();
            lockInfoToolTip.Show();
        }

        protected virtual void OnNavigate(object sender, CommandEventArgs e)
        {
            Navigate(e.CommandArgument);
        }

        protected abstract RadGrid Grid
        {
            get;
        }

        protected virtual BreadcrumbTrail BreadcrumbTrail
        {
            get { return null; }
        }

        protected abstract UpdatePanel GridUpdatePanel
        {
            get;
        }

        protected abstract string ManagementURL
        {
            get;
        }

        protected virtual string NodeIdParamName
        {
            get { return "id"; }
        }

        protected virtual string GridColumnNameHeaderText
        {
            get { return Translator.Translate("Medianamik_ContentManagement", 
                "ContentNameColumn"); }
        }

        protected virtual string GridColumnNameCssClass
        {
            get { return ""; }
        }

        protected virtual bool DestroyOnDelete
        {
            get { return false; }
        }

        protected virtual bool EnableSorting
        {
            get { return false; }
        }

        protected virtual Guid RootNodeId
        {
            get { return MedianamikModules.ContentManagement; }
        }

        private Guid? _parentNodeId;
        protected virtual Guid? ParentNodeId
        {
            get
            {
                if (!_parentNodeId.HasValue)
                {
                    if (ViewState[ParentNodeIdParamName] == null)
                    {
                        var strParentNodeId = Request.QueryString[ParentNodeIdParamName];

                        if (!String.IsNullOrEmpty(strParentNodeId)
                            && StringHelper.IsGuid(strParentNodeId, ref _parentNodeId))
                            ViewState[ParentNodeIdParamName] = _parentNodeId;
                    }
                    else
                        _parentNodeId = (Guid)ViewState[ParentNodeIdParamName];
                }

                return _parentNodeId;
            }
            set
            {
                ViewState["ParentNodeId"] = value;
                _parentNodeId = value;
                _parentNode = null;
            }
        }

        protected virtual string ParentNodeIdParamName
        {
            get
            {
                return DefaultParamNames.ParentNodeID;
            }
        }

        private Node _parentNode;
        protected virtual Node ParentNode
        {
            get
            {
                if (_parentNode == null && ParentNodeId.HasValue)
                {
                    _parentNode = NodeManager.GetNode(ParentNodeId.Value);

                    if (_parentNode != null)
                        _parentNode.DefaultCulture = CurrentEditionCulture;
                }

                return _parentNode;
            }
        }

        protected virtual GridActionOptions GridActionOptions
        {
            get
            {
                return GridActionOptions.Default;
            }
        }

        protected virtual GridOptions GridOptions
        {
            get
            {
                return GridOptions.None;
            }
        }

        protected abstract string ReturnUrl { get; }

        protected virtual void Navigate(object id)
        {
            Guid parentId;
            ParentNodeId = null;

            if (id != null && StringHelper.IsGuid(id.ToString(), out parentId))
                ParentNodeId = parentId;

            Navigate();
        }

        protected virtual void Navigate()
        {
            AddHistoryPoint(ParentNodeId.ToString());
            LoadBreadcrumbs();
        }

        protected virtual void AddHistoryPoint(string historyPoint)
        {
            if (MyScriptManager.IsInAsyncPostBack && (MyScriptManager.IsNavigating != true))
            {
                var pageState = new NameValueCollection { { "ParentNodeId", historyPoint } };
                MyScriptManager.AddHistoryPoint(pageState, Page.Title);
            }
        }

        protected virtual void LoadBreadcrumbs()
        {
            if (BreadcrumbTrail != null)
            {
                var breadcrumbs = new List<Breadcrumb> { new Breadcrumb(CurrentModule.ID.ToString(), CurrentModule.DisplayName) };

                if (ParentNode != null)
                {
                    var parentNodes = ParentNode.ParentNodes.ToList();
                    parentNodes.Insert(0, ParentNode);
                    parentNodes.RemoveAll(n => n.ID.Equals(CurrentModule.ID));
                    breadcrumbs.AddRange(parentNodes.OrderBy(n => n.Depth).Select(n => new Breadcrumb(n.ID.ToString(), n.DisplayName)));
                }

                BreadcrumbTrail.Breadcrumbs = breadcrumbs;
                BreadcrumbTrail.DataBind();
            }
        }
    }
}